#include "../头文件/AllFunction.h"

/**
 * @brief 点击该位置返回true
 *
 *        如果不是商家页面就不阻塞读取，
 * @param startX 表示起始横坐标
 * @param startY 表示起始纵坐标
 * @param endX 表示结束横坐标
 * @param endY 表示结束纵坐标
 * @param BlockState 阻塞读取的状态
 * @return true
 * @return false
 */
bool click_event(int startX, int startY, int endX, int endY, bool BlockState)
{
    int x = 0, y = 0;
    struct input_event input_info = {0};        // 保存触摸屏事件信息
    int fd = open("/dev/input/event0", O_RDWR); // 打开触摸屏文件
    while (1)
    {
        // 选择是否阻塞读取(阻塞的话 只能实现一个按键的点击)
        if (!BlockState)
        {
            // 设置为非阻塞 --begin--
            int status = fcntl(fd, F_GETFL);     // 1，获取当前的status 状态字
            status |= O_NONBLOCK;                // 2，将“非阻塞”属性加入status
            status = fcntl(fd, F_SETFL, status); // 3，将配置好的status 设置到fd 中
            // 设置完毕 --end--
        }

        ssize_t bytesRead = read(fd, &input_info, sizeof(input_info)); // 阻塞读取

        if (bytesRead == -1)
        {
            if (errno == EAGAIN)
                // 非阻塞读取，没有数据可读取
                continue;
            else
                break;
        }
        // 手松开
        if (EV_KEY == input_info.type && BTN_TOUCH == input_info.code && 0 == input_info.value)
        {
            printf("手松开触摸屏\n");
            // break; // 手松开退出
        }
        // 触摸屏绝对位移，x轴坐标发生改变
        if (EV_ABS == input_info.type && ABS_X == input_info.code)
        {
            x = input_info.value * 0.78125; // 保存x轴坐标(这里把显示屏x坐标优化成800)
            // x = input_info.value ;
        }
        // 触摸屏绝对位移，y轴坐标发生改变
        if (EV_ABS == input_info.type && ABS_Y == input_info.code)
        {
            y = input_info.value * 0.8; // 保存y轴坐标(这里把显示屏y坐标优化成480)
            // y = input_info.value; // 保存y轴坐标(这里把显示屏y坐标优化成800)
        }
        // printf("(%d, %d)\n", x, y);
        if (x >= startX && x <= endX)
            if (y >= startY && y <= endY)
            {
                close(fd);
                return true;
            }
    }
    return false;
}
/**
 * @brief 显示开机进度条
 *
 * @param progress 进度条的进度 800*20
 */
void show_progress_bar(int progress)
{
    int fd = open(COLORFILE, O_RDWR);

    if (fd < 0)
        return;

    int color[] = {0x000000, 0x0063BC, 0xFFFFFF};

    int *p = mmap(NULL, 800 * 480 * 4, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);

    // 这里的进度条是在高度460-480 在像素坐标上要减一
    for (int i = 460 - 1; i < 480; ++i)
    {
        for (int j = 0; j < progress; ++j)
        {
            if (j < 800)
                /*满绿色进度条为800*20*/
                if (j == 0 || j == 800 || i == 460 - 1 || i == 480)
                    *(p + j + i * 800) = color[BLACK];
                else
                    *(p + j + i * 800) = color[BLUE];
            else
                break;
        }
    }

    munmap(p, 800 * 480 * 4);
    close(fd);
}
/**
 * @brief 用于获得点击事件的类型
 *  根据点击的范围获得
 *
 * @return int 类型的值
 */
int get_click_type()
{
    int x = 0, y = 0;
    struct input_event input_info = {0};        // 保存触摸屏事件信息
    int fd = open("/dev/input/event0", O_RDWR); // 打开触摸屏文件
    while (1)
    {
        read(fd, &input_info, sizeof(input_info)); // 阻塞读取
                                                   // 手松开
        if (EV_KEY == input_info.type && BTN_TOUCH == input_info.code && 0 == input_info.value)
        {
            printf("手松开触摸屏\n");
            // break; // 手松开退出
        }
        // 触摸屏绝对位移，x轴坐标发生改变
        if (EV_ABS == input_info.type && ABS_X == input_info.code)
        {
            x = input_info.value * 0.78125; // 保存x轴坐标(这里把显示屏x坐标优化成800)
        }
        // 触摸屏绝对位移，y轴坐标发生改变
        if (EV_ABS == input_info.type && ABS_Y == input_info.code)
        {
            y = input_info.value * 0.8; // 保存y轴坐标(这里把显示屏y坐标优化成480)
        }
        // printf("(%d, %d)\n", x, y);
        // 商家用户选择页面
        if (objectselection == ALLOBJECT)
        {
            if (x >= 150 && x <= 270)
                if (y >= 280 && y <= 410)
                    return MERCHANT;
            if (x >= 540 && x <= 660)
                if (y >= 280 && y <= 410)
                    return USER;
        }
        // 用户注册登录页面
        else if (objectselection == USER)
        {
            if (x >= 150 && x <= 270)
                if (y >= 270 && y <= 400)
                    return REGISTER;
            if (x >= 510 && x <= 630)
                if (y >= 270 && y <= 400)
                    return LOGIN;
        }
    }
    return ALLOBJECT;
}

/**
 * @brief 显示键盘图片
 *
 */
void show_keyboard()
{
    keyBoardShow = true;
    show_anyjpg(265, 185, KEYBOARD_IMAGE);
}
/**
 * @brief 显示账号密码画布
 *
 */
void show_account_password_canvas()
{
    // account画布位置
    int account = 800 * 96 + 265;
    // password画布位置
    int password = 800 * 131 + 265;

    // 初始化Lcd
    int *lcd_mmap = lcd_init_mmap();

    // 打开字体文件
    font *f = fontLoad("/usr/share/fonts/DroidSansFallback.ttf");

    // 字体大小的设置
    fontSetSize(f, 30);

    // 创建两个画板（点阵图）
    // 账号画板
    bitmap *bm_Account = createBitmapWithInit(253, 30, 4, getColor(255, 16, 136, 221)); // 也可使用createBitmapWithInit函数，改变画板颜色
    // 密码画板
    bitmap *bm_Password = createBitmapWithInit(253, 30, 4, getColor(255, 16, 136, 221)); // 也可使用createBitmapWithInit函数，改变画板颜色
                                                                                         // bitmap *bm = createBitmap(288, 100, 4);

    // char buf[] = "创建一个画板32字体1大小的设置";

    // 将字体写到点阵图上
    // 如果当前点击的是账号框

    // 填写数据到字体框里
    if (strlen(InputAccount) != 0)
        fontPrint(f, bm_Account, 0, 0, InputAccount, getColor(0, 0, 0, 0), 600);
    else
        fontPrint(f, bm_Account, 0, 0, "电话号码(7-11位)", getColor(0, 16, 136, 128), 600);

    // 如果当前点击的是密码框

    // 填写数据到字体框里
    if (strlen(InputPassword) != 0)
    {
        char *current_password = hide_password(InputPassword);
        fontPrint(f, bm_Password, 0, 0, current_password, getColor(0, 0, 0, 0), 600);
        // 打印完后释放内存空间
        // 当前的密码指针不等于密码字符数组 (隐藏密码) ---> 释放内存
        if (current_password != InputPassword)
            free(current_password);
    }
    else
        fontPrint(f, bm_Password, 0, 0, "密码(6位)", getColor(0, 16, 136, 128), 600);

    // 把字体框输出到LCD屏幕上
    show_font_to_lcd(lcd_mmap + account, 0, 0, bm_Account);
    // 把字体框输出到LCD屏幕上
    show_font_to_lcd(lcd_mmap + password, 0, 0, bm_Password);
    // 关闭字体，关闭画板
    fontUnload(f);
    destroyBitmap(bm_Account);
    destroyBitmap(bm_Password);

    lcd_close_mmap(lcd_mmap);
}
/**
 * @brief 一个页面多个点击事件专门用的函数
 *
 * 在内部修改跳转功能的参数
 *
 * (265,95)-(518,125) 账号画布
 *
 * (265,130)-(518,160) 密码画布
 *
 * (20,20)-(70,45) 返回键
 *
 * @param BlockState 是否阻塞传参
 */
Flag all_click_event(bool BlockState)
{
    int x = 0, y = 0;
    struct input_event input_info = {0};        // 保存触摸屏事件信息
    int fd = open("/dev/input/event0", O_RDWR); // 打开触摸屏文件
    while (1)
    {
        // 选择是否阻塞读取(阻塞的话 只能实现一个按键的点击)
        if (!BlockState)
        {
            // 设置为非阻塞 --begin--
            int status = fcntl(fd, F_GETFL);     // 1，获取当前的status 状态字
            status |= O_NONBLOCK;                // 2，将“非阻塞”属性加入status
            status = fcntl(fd, F_SETFL, status); // 3，将配置好的status 设置到fd 中
            // 设置完毕 --end--
        }

        ssize_t bytesRead = read(fd, &input_info, sizeof(input_info)); // 阻塞读取

        if (bytesRead == -1)
        {
            if (errno == EAGAIN)
                // 非阻塞读取，没有数据可读取
                continue;
            else
                break;
        }
        // 手松开
        if (EV_KEY == input_info.type && BTN_TOUCH == input_info.code && 0 == input_info.value)
        {
            printf("手松开触摸屏\n");
            // break; // 手松开退出
        }
        // 触摸屏绝对位移，x轴坐标发生改变
        if (EV_ABS == input_info.type && ABS_X == input_info.code)
        {
            x = input_info.value * 0.78125; // 保存x轴坐标(这里把显示屏x坐标优化成800)
            // x = input_info.value ;
        }
        // 触摸屏绝对位移，y轴坐标发生改变
        if (EV_ABS == input_info.type && ABS_Y == input_info.code)
        {
            y = input_info.value * 0.8; // 保存y轴坐标(这里把显示屏y坐标优化成480)
            // y = input_info.value; // 保存y轴坐标(这里把显示屏y坐标优化成480)
        }
        // printf("(%d, %d)\n", x, y);
        // 点击账号画布
        if (x >= 265 && x <= 518 && y >= 95 && y <= 125)
        {
            clickobject = ACCOUNT;
            return ACCOUNT;
        }
        // 点击密码画布
        else if (x >= 265 && x <= 518 && y >= 130 && y <= 160)
        {
            clickobject = PASSWORD;
            return PASSWORD;
        }
        // 关闭键盘
        else if (keyBoardShow && x != 0 && (x <= 265 || x >= 518) && (y >= 160 && y <= 480))
        {
            clickobject = NONE;
            keyBoardShow = false;
            return CLOSEKEYBOARD;
        }
        // 点击返回键
        else if (x >= 10 && x <= 70 && y >= 10 && y <= 60)
        {
            clickobject = NONE;
            if (!isChangePassword)
                goto_user(USER_IMAGE);
            return RETURN;
        }
        // 点击小眼睛
        else if (x >= 525 && x <= 555 && y >= 130 && y <= 160)
            return SMALLEYE;

        // 数字键盘的点击
        if (x >= 265 && x <= 315 && y >= 185 && y <= 223)
            // 清除键
            return CLEAR;
        else if (x >= 389 && x <= 439 && y >= 185 && y <= 223)
            // 删除键
            return DELETE;
        else if (x >= 451 && x <= 501 && y >= 293 && y <= 388)
            // 确认键
            return CONFIRM;
        // 以下是数字键的点击
        else if (x >= 265 && x <= 315 && y >= 239 && y <= 277)
            return SEVEN;
        else if (x >= 327 && x <= 377 && y >= 239 && y <= 277)
            return EIGHT;
        else if (x >= 389 && x <= 439 && y >= 239 && y <= 277)
            return NINE;
        else if (x >= 265 && x <= 315 && y >= 293 && y <= 331)
            return FOUR;
        else if (x >= 327 && x <= 377 && y >= 293 && y <= 331)
            return FIVE;
        else if (x >= 389 && x <= 439 && y >= 293 && y <= 331)
            return SIX;
        else if (x >= 265 && x <= 315 && y >= 347 && y <= 385)
            return ONE;
        else if (x >= 327 && x <= 377 && y >= 347 && y <= 385)
            return TWO;
        else if (x >= 389 && x <= 439 && y >= 347 && y <= 385)
            return THREE;
        else if (x >= 265 && x <= 377 && y >= 401 && y <= 439)
            return ZERO;
    }
    return -1;
}
/**
 * @brief 关闭键盘
 *
 */
void close_keyboard()
{
    if (!isChangePassword)
    {
        show_anyjpg(0, 0, ACCOUNTPASSWORD);
        if (registerOrLogin == REGISTER)
            show_anyjpg(290, 40, LOGO_REGISTER);
        else
            show_anyjpg(290, 40, LOGO_LOGIN);
        show_account_password_canvas();
    }
    else
        change_password();
}
/**
 * @brief 清除填写框的数据
 *
 * @param flag 当前是什么填写框
 */
void clear_data(Flag flag)
{
    // 登录和注册界面的清除键
    if (!isChangePassword)
    {
        if (flag == ACCOUNT)
            memset(InputAccount, 0, sizeof(InputAccount));
        else if (flag == PASSWORD)
            memset(InputPassword, 0, sizeof(InputPassword));
    }
    // 修改密码界面的清除键
    else
    {
        if (flag == ACCOUNT)
            memset(InputOldPassword, 0, sizeof(InputOldPassword));
        else if (flag == PASSWORD)
            memset(InputNewPassword, 0, sizeof(InputNewPassword));
    }
}
/**
 * @brief 删除填写框的一个数据
 *
 * @param flag 当前是什么填写框
 */
void delete_data(Flag flag)
{
    if (!isChangePassword)
    {
        if (flag == ACCOUNT)
        {
            int length = strlen(InputAccount);
            if (length > 0)
                InputAccount[length - 1] = '\0';
        }
        else if (flag == PASSWORD)
        {
            int length = strlen(InputPassword);
            memset(InputPassword + length - 1, 0, 1);
        }
    }
    else
    {
        if (flag == ACCOUNT)
        {
            int length = strlen(InputOldPassword);
            if (length > 0)
                InputOldPassword[length - 1] = '\0';
        }
        else if (flag == PASSWORD)
        {
            int length = strlen(InputNewPassword);
            memset(InputNewPassword + length - 1, 0, 1);
        }
    }
}
/**
 * @brief 确认键 用户点击后将数据传回数据库(文本文件)保存
 *
 * @param clickobject 当前页面信息(注册账号/登录账号)
 */
void confirm_data(ClickObject clickobject)
{
    // 注册页面
    if (clickobject == REGISTER)
    {
        // 在文本文件里查找是否有该账号
        // 判断注册的账号和密码是否合法
        // 账号位7-11位 密码为6位
        UserData user;
        user.Account = strdup(InputAccount);
        if (strlen(user.Account) < 7 || strlen(user.Account) > 11)
        {
            show_anyjpg(265, 185, REGISTER_FAIL);
            sleep(2);
            goto_register();
            return;
        }
        user.Password = strdup(InputPassword);
        if (strlen(user.Password) != 6)
        {
            show_anyjpg(265, 185, REGISTER_FAIL);
            sleep(2);
            goto_register();
            return;
        }
        user.RegisterTime = getDate();
        user.LastLoginTime = getDate();
        user.Phone = strdup(InputAccount);
        user.ChargingCard.Account = strdup(InputAccount);
        user.ChargingCard.CardId = calloc(21, sizeof(char));
        generate_cardid(user.ChargingCard.CardId);
        user.ChargingCard.Money = 99.0;
        user.ChargingCard.Validity = malloc(50 * sizeof(char)); // 分配足够的内存
        initialize_card_validity(user.RegisterTime, user.ChargingCard.Validity);
        if (StoreData(&user))
        {
            // 注册成功
            show_anyjpg(265, 185, REGISTER_SUCCESS);
            sleep(3);
            goto_login();
        }
        else
        {
            // 数据存储异常(数据库已有该账号)
            // 等待三秒 并重新进入注册界面
            sleep(3);
            goto_register();
        }
    }
    // 登录页面
    else if (clickobject == LOGIN && !isChangePassword)
    {
        UserData *user = GetUserData(InputAccount);
        // 获取不到数据库的信息 密码不一致
        if (user == NULL || strcmp(user->Password, InputPassword) != 0)
        {
            show_anyjpg(265, 185, LOGIN_FAIL);
            sleep(2);
            goto_login();
            return;
        }
        else
        {
            user->LastLoginTime = getDate();
            StoreData(user);
            user = GetUserData(InputAccount);
            show_anyjpg(265, 185, LOGIN_SUCCESS);
            CurrentUser = *user;
            sleep(2);
            functions();
        }
    }
    // 修改密码页面
    else if (clickobject == LOGIN && isChangePassword)
    {
        // 原密码和旧密码不一致
        if (strcmp(InputOldPassword, CurrentUser.Password) != 0)
        {
            show_anyjpg(265, 185, OLD_PASSWORD_WRONG);
            memset(InputOldPassword, 0, sizeof(InputOldPassword));
            memset(InputNewPassword, 0, sizeof(InputNewPassword));
            sleep(2);
            change_password();
            return;
        }
        // 修改数据库里的密码
        else
        {
            if (strlen(InputNewPassword) != 6)
            {
                show_anyjpg(265, 185, NEW_PASSWORD_WRONG);
                memset(InputOldPassword, 0, sizeof(InputOldPassword));
                memset(InputNewPassword, 0, sizeof(InputNewPassword));
                sleep(2);
                change_password();
                return;
            }
            strcpy(CurrentUser.Password, InputNewPassword);
            // 将数据存到数据库里
            StoreData(&CurrentUser);
            CurrentUser = *(GetUserData(InputAccount));
            show_anyjpg(265, 185, NEW_PASSWORD_SUCCESS);
            memset(InputOldPassword, 0, sizeof(InputOldPassword));
            memset(InputNewPassword, 0, sizeof(InputNewPassword));
            smallEyeState = true;
            sleep(2);
        }
    }
}
/**
 * @brief 查找用户数据是否存在数据库
 *
 * @param account 用户的账号
 * @param users 临时存储文件
 * @param user_count 注册用户在数据库的个数
 * @return int 当前用户的索引
 */
int find_user(const char *account, UserData *users, int user_count)
{
    for (int i = 0; i < user_count; i++)
    {
        if (strcmp(users[i].Account, account) == 0)
        {
            return i; // 返回用户索引
        }
    }
    return -1; // 未找到
}
/**
 * @brief 生成一个20位随机数的充电卡编号
 *
 * @param cardid 充电卡编号
 */
void generate_cardid(char *cardid)
{
    const char charset[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
    int i;

    // 初始化随机数种子
    srand((unsigned int)time(NULL));

    for (i = 0; i < 20; i++)
    {
        // 从charset中随机选择一个字符
        cardid[i] = charset[rand() % (sizeof(charset) - 1)];
    }
    cardid[20] = '\0'; // 字符串结束符
}

// 自定义的日期解析函数，替代 strptime
int my_strptime(const TextType input, const TextType format, struct tm *tm)
{
    // sscanf解析不了 %Y-%m-%d %H:%M:%S
    // 所以只能用 %4d-%2d-%2d %2d:%2d:%2d 代替了
    // 使用 sscanf 解析输入字符串
    int n = sscanf(input, format,
                   &tm->tm_year, &tm->tm_mon, &tm->tm_mday,
                   &tm->tm_hour, &tm->tm_min, &tm->tm_sec);
    if (n != 6)
    {
        fprintf(stderr, "sscanf 解析失败，返回值为 %d, 输入字符串: %s\n", n, input);
        return -1; // 解析失败
    }

    // 调整年份和月份
    tm->tm_year -= 1900; // 年份需要减去 1900
    tm->tm_mon -= 1;     // 月份范围是 0-11

    return 0; // 解析成功
}

/**
 * @brief 初始化充电卡的有效期 (在注册时间的基础上上3年)
 *
 * @param register_time 注册时间(字符串)
 * @param validity 有效期(字符串)
 */
void initialize_card_validity(const TextType register_time, TextType validity)
{
    struct tm reg_tm = {0}; // 初始化 tm 结构体

    // 解析注册时间
    if (my_strptime(register_time, "%4d-%2d-%2d %2d:%2d:%2d", &reg_tm) != 0)
    {
        fprintf(stderr, "解析注册时间失败！\n");
        return;
    }

    // 调整时间为 3 年后的时间
    reg_tm.tm_year += 3;
    if (mktime(&reg_tm) == -1)
    {
        fprintf(stderr, "mktime 调整时间失败！\n");
        return;
    }

    // 格式化时间为字符串
    strftime(validity, 50, "%Y-%m-%d %H:%M:%S", &reg_tm);
}

// 辅助函数：释放 UserData 结构体中的动态内存
void free_user_data(UserData *user)
{
    if (user->Account != NULL)
    {
        free(user->Account);
        user->Account = NULL;
    }
    if (user->Password != NULL)
    {
        free(user->Password);
        user->Password = NULL;
    }
    if (user->RegisterTime != NULL)
    {
        free(user->RegisterTime);
        user->RegisterTime = NULL;
    }
    if (user->LastLoginTime != NULL)
    {
        free(user->LastLoginTime);
        user->LastLoginTime = NULL;
    }
    if (user->Phone != NULL)
    {
        free(user->Phone);
        user->Phone = NULL;
    }
    if (user->ChargingCard.Account != NULL)
    {
        free(user->ChargingCard.Account);
        user->ChargingCard.Account = NULL;
    }
    if (user->ChargingCard.CardId != NULL)
    {
        free(user->ChargingCard.CardId);
        user->ChargingCard.CardId = NULL;
    }
    if (user->ChargingCard.Validity != NULL)
    {
        free(user->ChargingCard.Validity);
        user->ChargingCard.Validity = NULL;
    }
    user->ChargingCard.Money = 0; // 重置金额
}

// 初始化 UserData 结构体
void init_user_data(UserData *user)
{
    user->Account = NULL;
    user->Password = NULL;
    user->RegisterTime = NULL;
    user->LastLoginTime = NULL;
    user->Phone = NULL;
    user->ChargingCard.Account = NULL;
    user->ChargingCard.CardId = NULL;
    user->ChargingCard.Money = 0;
    user->ChargingCard.Validity = NULL;
    // 直接测试后面功能界面
    // registerOrLogin = LOGIN;
    // objectselection = USER;
    // user->Account = "1234567";
    // user->Password = "123456";
    // user->RegisterTime = "2025-01-20 16:13:54";
    // user->LastLoginTime = "2025-01-20 16:13:54";
    // user->Phone = NULL;
    // user->ChargingCard.Account = "1234567";
    // user->ChargingCard.CardId = "I9IGMKTXPX9UE6CZPDU3";
    // user->ChargingCard.Money = 0.0;
    // user->ChargingCard.Validity = "2028-01-20 16:13:54";
}
/**
 * @brief 将文本打印在画板上
 *
 * @param width 输出框的宽
 * @param height 输出框的高
 * @param byteperpixel 当前屏幕一个像素的数据大小4个字节（32位色深）
 * @param mapcolor 输出框颜色值	getColor(A, R, G, B)
 * @param fontsize 设置字体大小
 * @param x 字体的位置 X轴
 * @param y 字体的位置 Y轴
 * @param text 字体文本
 * @param fontcolor 字体颜色 getColor(A, R, G, B)
 * @param maxWidth 一行显示字体的最大宽度  （例如：字体大小为32，假设设置为64则一行显示两个字体，超过就换行显示）
 * @param print_index LCD映射后的首地址为左上角，该值是修改映射后的位置
 */
void show_text(u32 width, u32 height, u32 byteperpixel, u32 mapcolor, int fontsize, s32 x, s32 y, char *text, u32 fontcolor, s32 maxWidth, int print_index)
{
    // 初始化Lcd
    int *lcd_mmap = lcd_init_mmap();

    // 打开字体文件
    font *f = fontLoad("/usr/share/fonts/DroidSansFallback.ttf");

    // 字体大小的设置
    fontSetSize(f, fontsize);

    // 创建两个画板（点阵图）
    // 账号画板
    bitmap *bm = createBitmapWithInit(width, height, byteperpixel, mapcolor); // 也可使用createBitmapWithInit函数，改变画板颜色
    // bitmap *bm = createBitmap(width, height, byteperpixel);

    // char buf[] = "创建一个画板32字体1大小的设置";

    // 将字体写到点阵图上

    fontPrint(f, bm, x, y, text, fontcolor, maxWidth);

    // 把字体框输出到LCD屏幕上
    show_font_to_lcd(lcd_mmap + print_index, 0, 0, bm);
    // 关闭字体，关闭画板
    fontUnload(f);
    destroyBitmap(bm);
    lcd_close_mmap(lcd_mmap);
}

/**
 * @brief 设置一个新的充电桩
 *
 * @param devicestate 设备的状态(True/False)
 * @param position 设备的地点(拼音)
 */
void Init_Device(bool devicestate, TextType position)
{
    char buffer[50];
    bool device_exists = false;
    FILE *file = fopen(DEVICE_DATA, "r+"); // 打开文件以文本写入模式
    TextType DeviceId = malloc(21 * sizeof(char));
    strcpy(DeviceId, position);
    strcat(DeviceId, "_");
    const char charset[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
    int i;

    // 初始化随机数种子
    srand((unsigned int)time(NULL));

    for (i = strlen(DeviceId); i < 20; i++)
    {
        // 从charset中随机选择一个字符
        DeviceId[i] = charset[rand() % (sizeof(charset) - 1)];
    }
    DeviceId[20] = '\0'; // 字符串结束符
    if (file == NULL)
    {
        printf("无法打开文件\n");
        return;
    }
    else
    {
        // 读取文件并检查设备ID是否存在
        while (fgets(buffer, 50, file))
        {
            if (sscanf(buffer, "DeviceId: %s", buffer) == 1)
            {
                if (strcmp(buffer, DeviceId) == 0)
                {
                    device_exists = true;
                    break;
                }
            }
            // 读取其他行
            while (fgets(buffer, 50, file))
            {
                if (strcmp(buffer, "----------------------------------------------------\n") == 0)
                {
                    break;
                }
            }
        }
    }

    if (device_exists)
    {
        // 更新设备信息
        fseek(file, -strlen(DeviceId) - 1, SEEK_CUR); // 回退到设备ID的开始位置
        fprintf(file, "DeviceId: %s\n", DeviceId);
        fprintf(file, "DeviceType: %s\n", NULL); // 假设设备类型为"Charger"
        fprintf(file, "DeviceState: %s\n", devicestate ? "True" : "False");
        fprintf(file, "DevicePosition: %s\n", position);
        fprintf(file, "----------------------------------------------------\n");
    }
    else
    {
        // 在文件尾部追加新的设备信息
        fseek(file, 0, SEEK_END);
        fprintf(file, "DeviceId: %s\n", DeviceId);
        fprintf(file, "DeviceType: %s\n", NULL); // 假设设备类型为"Charger"
        fprintf(file, "DeviceState: %s\n", devicestate ? "True" : "False");
        fprintf(file, "DevicePosition: %s\n", position);
        fprintf(file, "----------------------------------------------------\n");
    }

    fclose(file);
    free(DeviceId);
}